package net.takela.common.webflux.security.handler;

import net.takela.common.webflux.security.SecurityConfigProperties;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.server.authorization.AuthorizationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import reactor.core.publisher.Mono;

import java.util.Optional;

/**
 * 校验用户是否拥有操作
 */
@Component
public class AppAuthorizationManager implements ReactiveAuthorizationManager<AuthorizationContext> {

    private final SecurityConfigProperties securityConfigProperties;
    private static AntPathMatcher antPathMatcher = new AntPathMatcher();
    /**
     * 
     */
    public AppAuthorizationManager(SecurityConfigProperties securityConfigProperties) {
        this.securityConfigProperties = securityConfigProperties;
    }

    
    /**
     * 
     */
    @Override
    public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, AuthorizationContext authorizationContext) {
        return authentication.map(auth -> {

            //SecurityUserDetails userSecurity = (SecurityUserDetails) auth.getPrincipal();
            String path = authorizationContext.getExchange().getRequest().getURI().getPath();
            if (securityConfigProperties.getPermitUrls() != null){
                Optional<String> op = securityConfigProperties.getAnonymousUrls().stream().filter(e -> antPathMatcher.match(e, path)).findFirst();
                if (op.isPresent()){
                    return new AuthorizationDecision(true);
                }
            }
            if (path.startsWith("/openapi") || path.contains("test")){
                return new AuthorizationDecision(true);
            }
//            for (GrantedAuthority authority : auth.getAuthorities()){
//                if (authority.getAuthority().equals("ROLE_USER")&&path.contains("/user/normal"))
//                    return new AuthorizationDecision(true);
//                else if (authority.getAuthority().equals("ROLE_ADMIN")&&path.contains("/user/admin"))
//                    return new AuthorizationDecision(true);
////对客户端访问路径与用户角色进行匹配
//            }
            return new AuthorizationDecision(false);
        }).defaultIfEmpty(new AuthorizationDecision(false));
    }

    
    /**
     * 
     */
    @Override
    public Mono<Void> verify(Mono<Authentication> authentication, AuthorizationContext object) {
        return ReactiveAuthorizationManager.super.verify(authentication, object);
    }
}
